在程序开发中,如何快速的查找定位问题是一项非常重要的基本功。在实际开发过程中,或多或少都会遇到程序出现问题导致无法正常运行的情况,因此,调试代码就变成了一项无法避免的工作。这里简单介绍下如何调试 node.js 程序。
使用 console.log
Node 提供了全局的 console 对象,该对象可以输出格式化的字符串。
console.log 是调试 Node 模块最简单的工具,console.log 主要有两个作用:一是将对象序列化为一个字符串,另一个是向标准输出流输出结果。
使用 console.log 检查对象:
1 | const obj = { |
这段代码将打印出以下信息:
1 | { a: 1, b: 2 } |
注意:实质上 console.log 没有进行任何格式化操作,而是 console.log 内部调用了 util.format 将传入的参数格式化,并且将结果输出到标准输出流中。
console.log 函数只检查对象的自有可枚举属性,即在原型链上的属性以及不可枚举的属性都不会显示。
例如:
1 | const obj = Object.defineProperty({ |
不可枚举属性 a 不会显示,这段代码将打印出以下信息:
1 | { b: 2 } |
console.log 函数可以通过 util.format 函数提供向字符串中插入数值的能力,在字符串中使用 % 前缀作占位符。
例如:
1 | console.log('an object: %j', {a: 1, b: 2}) |
这段代码将打印出以下信息:
1 | an object: {"a":1,"b":2} |
%j 是一个 JSON 占位符。即如果参数包含循环引用,则替换为字符串 ‘[Circular]’。
当然除了 console.log 函数,还可以使用 console 对象的其他函数调试代码,例如:console.error、console.table、console.info等等。
注意:在 Node 中,如果向进程的输出流中写入数据是一种阻塞操作,写入记录时会阻塞事件循坏。因此,在实际项目中应避免使用 console.log。
使用 debugger 调试器
使用 console.log 检查变量虽然简单易用,但它也有很糟糕的一面,在复杂程序中很难定位和发现问题,程序输出冗长,阻塞事件循环等。
庆幸的是,V8 引擎导出了一个支持 Node 的调试接口。因此,可以使用 Node 内置的调试器调试你的程序。
创建一个错误的程序:
1 | var n = 0 |
运行程序,输出结果如下:
1 | n before: 1 |
变量 n 并没有如期递增,接下来使用调试模式启动 Node 调试程序:
1 | node --inspect index.js |
这样就会以调试模式启动 Node,可以看到调试器的提示信息如下:
1 | Debugger listening on ws://127.0.0.1:9229/a94b1d29-81cb-461b-8abc-f1bf87c767b1 |
调试的程序代码非常少,所以调试立即就完成结束了。
可以通过命令在程序第一行设置断点:
1 | node --inspect-brk index.js |
调试器提示信息如下:
1 | Debugger listening on ws://127.0.0.1:9229/def735ed-3a2a-4772-a40d-077939e76b83 |
这样调试就不会立即结束。
接着,打开 Chrome 浏览器,在地址栏输入:
1 | chrome://inspect/#devices |
在界面 Remote Target 标签内容中找到要调试的目标(Target)文件,点击目标中的 inspect 链接就可以进入浏览器调试面板调试程序了。接下来的调试操作方式和平时调试普通 JavaScript 代码一样。